package com.lucy.property.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.lucy.common.constant.HttpStatus;
import com.lucy.common.domain.ResponseDTO;
import com.lucy.common.domain.vo.CascaderVO;
import com.lucy.property.entity.BuildingUnit;
import com.lucy.property.entity.PropertyBuilding;
import com.lucy.property.entity.PropertyUnit;
import com.lucy.property.params.*;
import com.lucy.property.service.BuildingUnitService;
import com.lucy.property.service.PropertyBuildingService;
import com.lucy.property.service.PropertyUnitService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.checkerframework.checker.units.qual.C;
import org.simpleframework.xml.Path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("building")
@Api(tags = "楼栋单元管理")
public class BuildingUnitController {
    @Autowired
    BuildingUnitService service;

    @Autowired
    PropertyUnitService unitService;

    @Autowired
    PropertyBuildingService buildingService;

    @PostMapping("units")
    @ApiOperation(value = "楼栋单元新建",notes = "")
    public ResponseDTO<Object> buildingUnitCreate(@RequestBody @Validated BuildingUnitCreateParams params){
        BuildingUnit unit = new BuildingUnit();
        // 获取楼栋信息
        Optional<PropertyBuilding> buildingOp = buildingService.getOne(params.getBuildingId());
        if (!buildingOp.isPresent()){
            return ResponseDTO.wrap(HttpStatus.NOT_FOUND,"楼栋信息不存在");
        }
        PropertyBuilding building = buildingOp.get();
        // 忽略id 复制属性
        BeanUtil.copyProperties(building,unit,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true).setIgnoreProperties("id"));
        BeanUtil.copyProperties(params,unit,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        // 设置基础属性
        unit.setInUsedNum(0);
        unit.setInRentNum(0);
        unit.setInFreeNum(params.getHouseNum());
        return ResponseDTO.succData(
                service.saveOne(unit)
        );
    }

    @DeleteMapping("units/{id}")
    @ApiOperation(value = "楼栋单元删除",notes = "")
    public ResponseDTO<Object> buildingUnitDelete(@PathVariable("id") String id){
        service.deleteOne(id);
        return ResponseDTO.succMsg("删除成功");
    }

    @PutMapping("units")
    @ApiOperation(value = "楼栋单元更新",notes = "")
    public ResponseDTO<Object> buildingUnitUpdate(@RequestBody @Validated BuildingUnitUpdateParams params){
        Optional<BuildingUnit> uniOp = service.getOne(params.getId());
        if (!uniOp.isPresent()){
            return ResponseDTO.wrap(HttpStatus.NOT_FOUND);
        }
        BuildingUnit unit = uniOp.get();
        BeanUtil.copyProperties(params,unit,CopyOptions.create().setIgnoreError(true).setIgnoreNullValue(true));
        return ResponseDTO.succData(
                service.updateOne(unit)
        );
    }

    @GetMapping("units")
    @ApiOperation(value = "楼栋单元列表",notes = "")
    public ResponseDTO<Object> buildingUnitListQuery(BuildingQueryParams params){
        Sort sort;
        if("DESC".equalsIgnoreCase(params.getOrder())){
            sort = Sort.by(Sort.Direction.DESC, params.getSortBy());
        }else {
            sort = Sort.by(Sort.Direction.ASC, params.getSortBy());
        }

        // tips : 页码对应 - 1
        Pageable pageable = PageRequest.of(params.getPageNum() - 1 , params.getPageSize(), sort);
        /*
        构建 Example
         */
        BuildingUnit unit = new BuildingUnit();
        BeanUtil.copyProperties(params,unit,CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        Example<BuildingUnit> example = Example.of(unit);
        return ResponseDTO.succData(service.getAll(pageable,example));
    }

    @GetMapping("units/{id}")
    @ApiOperation(value = "楼栋单元查询",notes = "")
    public ResponseDTO<Object> buildingUnitQuery(@PathVariable("id") String id){
        Optional<BuildingUnit> unitOp = service.getOne(id);
        return unitOp.<ResponseDTO<Object>>map(ResponseDTO::succData).orElseGet(() -> ResponseDTO.wrap(HttpStatus.NOT_FOUND));
    }

    public List<CascaderVO<String>> buildCascader(List<BuildingUnit> units, Integer deep, String rootId){
        if (deep.equals(1)){
            List<CascaderVO<String>> vos = new ArrayList<>();
            // 楼栋
            for (BuildingUnit unit:units){
                if (unit.getUnitId().equals(rootId)){
                    CascaderVO<String> vo = new CascaderVO<>();
                    vo.setValue(unit.getBuildingId());
                    vo.setLabel(unit.getBuildingName());
                    vo.setChildren(buildCascader(units,2,unit.getBuildingId()));
                    vos.add(vo);
                }
            }
            return vos;
        }else if (deep.equals(2)){
            // 单元
            List<CascaderVO<String>> vos = new ArrayList<>();
            // 楼栋
            for (BuildingUnit unit:units){
                if (unit.getBuildingId().equals(rootId)){
                    CascaderVO<String> vo = new CascaderVO<>();
                    vo.setValue(unit.getId());
                    vo.setLabel(unit.getBuildingUnitName());
                    vo.setChildren(null);
                    vos.add(vo);
                }
            }
            return vos;
        }
        return null;
    }

    @GetMapping("units/cascader")
    @ApiOperation(value = "楼栋单元级联",notes = "")
    public ResponseDTO<Object> buildingUnitCascader(){
        BuildingUnit unit = new BuildingUnit();
        Example<BuildingUnit> example = Example.of(unit);
        List<BuildingUnit> units = service.getExample(example);
        List<CascaderVO<String>> vos = new ArrayList<CascaderVO<String>>();

        // 获取全部
        List<String> unitIds = units.stream().map(BuildingUnit::getUnitId).distinct().collect(Collectors.toList());
        List<PropertyUnit> punits = unitService.getByIds(unitIds);
        for (PropertyUnit t:punits){
            CascaderVO<String> cascaderVO = new CascaderVO<>();
            cascaderVO.setValue(t.getId());
            cascaderVO.setLabel(t.getUnitName());
            cascaderVO.setChildren(buildCascader(units,1,t.getId()));
            vos.add(cascaderVO);
        }
        return ResponseDTO.succData(
                vos
        );
    }
}
